home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DS-CD ROM 2 1993 August
/
DS CD-ROM 2.Ausgabe (August 1993).iso
/
programm
/
ds0257
/
demo.exe
/
QUEUES.DEM
< prev
next >
Wrap
Text File
|
1992-02-16
|
27KB
|
841 lines
; ----------------------------
; QUEUES.DEM - Demoprogramm für die Routinen aus QUEUES.BIB
; (und implizit: MQUEUE.LIB, SQUEUE.LIB und MEMORY.LIB)
; (für den A86)
;
; (c) Bernd Schemmer 1992
; Letzter Update: 15.02.1992
;
; Übersetzen:
; A86 MQUEUE.DEM DEMOS.INC TO MQUEUE.COM
;
; Hinweis: Die Environment-Variable 'A86' muß den Dateinamen 'MACROS.MAC'
; enthalten und die .LIB-Dateien müssen über die Datei A86.LIB
; erreichbar sein.
;
; ---------------------------
jmp start
; ----------------------------
; Meldungen und Fehlermeldungen
logo db CR,LF
db 'QUEUES.DEM - Demoprogramm für die Routinen aus QUEUES.BIB' ,CR,LF
db '----------------------------------------------------------',CR,LF
db 'Das Programm führt folgende Arbeitsschritte durch: ',CR,LF
db '1. Lesen der Eingabe-Datei ',CR,LF
db '2. Einrichten von 2 meldungsorientierten Queuen und ',CR,LF
db ' 1 streamorientierten Queue ',CR,LF
db '3. Verteilen der Zeilen der Eingabe-Datei auf die 3 Queuen',CR,lF
db ' nach folgenden Algorithmus: ',CR,LF
db ' Alle Zeilen, die mit einem Semikolon beginnen kommen ',CR,LF
db ' in die erste Queue, alle weiteren Zeilen, die ein Semi-',CR,LF
db ' kolon enthalten kommen in die zweite Queue und alle ',CR,LF
db ' restlichen Zeilen kommen in die dritte Queue. ',CR,LF
db '4. Schreiben der 3 Queuen in die Ausgabe-Datei ',CR,LF
db CR,LF
db 'Das Demo muß folgendermaßen aufgerufen werden:' ,CR,LF
db ' QUEUES.COM eingabedatei ausgabedatei' ,CR,LF
db CR,LF,CR,LF
db 'Bitte eine Taste drücken (ESC = Programm-Abbruch) ...' ,CR,LF
db CR,LF
GETLENGTH logo
; Meldungen
MakeMsg ReadMsg, '--- Lese die Eingabe-Datei ...'
MakeMsg Open1Msg, '--- Öffne die 1. Queue ...'
MakeMsg Open2Msg, '--- Öffne die 2. Queue ...'
MakeMsg Open3Msg, '--- Öffne die 3. Queue ...'
MakeMsg ProceedMsg, '--- Verteile die Zeilen auf die Queuen ...'
MakeMsg Write1Msg, '--- Schreibe die 1. Queue in die Ausgabe-Datei ...'
MakeMsg Write2Msg, '--- Schreibe die 2. Queue in die Ausgabe-Datei ...'
MakeMsg Write3Msg, '--- Schreibe die 3. Queue in die Ausgabe-Datei ...'
MakeMsg Close1Msg, '--- Schliesse die Queue 1 ...'
MakeMsg Close2Msg, '--- Schliesse die Queue 2 ...'
MakeMsg Close3Msg, '--- Schliesse die Queue 3 ...'
; Fehlermeldungen
MakeMsg ParamError, '*** Fehlerhaften Parameter oder zuwenig Parameter angegeben.'
MakeMsg MemoryError, '*** Zuwenig freier Speicher.'
MakeMsg OFileError, '*** Fehler beim Öffnen der Ausgabe-Datei'
MakeMsg IFileError, '*** Fehler beim Lesen der Eingabe-Datei'
MakeMsg IFileError1, '*** Eingabe-Datei ist zu groß'
MakeMsg WriteFileError, '*** Fehler beim Schreiben der Ausgabe-Datei.'
MakeMsg ReadFileError, '*** Fehler beim Lesen der Datei.'
MakeMsg OutputError, '*** Fehler beim Schreiben in die Ausgabe-Datei.'
OutputFileHandle dw 0 ; Handle der Ausgabe-Datei
InputFileHandle dw 0 ; Handle der Eingabe-Datei
InputFileLength dw 0 ; Größe der Eingabe-Datei
InputFileOff dw 0 ; Pufferzeiger für die Eingabe-Datei
InputFileSeg dw 0 ; Segment des Speicherblocks zum Lesen der
; Eingabe-Datei
Queue1Handle dw 0 ; Handles für die Queuen
Queue2Handle dw 0
Queue3Handle dw 0
; Puffer für die Zeilen
LineBuffer db 0,257 dup 20h
MaxQueueHandles EQU 05h ; das Demo benötigt max. 3 Queuen
; ----------------------------
start:
call ShowLogoAndAsk ; Logo ausgeben, Speicherblock verkleinern
; und Taste lesen
; ----------------------------
l2:
Write_String ReadMsg
; Ein- und Ausgabe-Dateien eröffnen
call OpenInAndOutputFiles
IF c jmp ErrorEnde1 ; Fehler!
; ----------------------------
; Größe für die 3 Queuen berechnen
mov bx,0FFFFh
call GetMemoryBlock
cmp ax,08
je >l1
stc
call CheckQueueError
if c jmp ErrorEnde1
l1:
mov ax,bx ; AX = freier Speicher in Paragraphen
mov cx,0FFFFh ; CX = 1 Segment in Byte
cmp ax,3000h
jae >l1 ; 1 Segment pro Queue ist möglich
shl ax,1
shl ax,1 ; AX = (freier Speicher in Byte) / 4
mov cx,ax ; CX = Größe für eine Queue in Byte
l1:
; ----------------------------
push cx
Write_String Open1Msg
; Öffnen der ersten Queue (meldungsorientiert)
mov ax,01h
call OpenQueue
call CheckQueueError
if c jmp ErrorEnde1
mov Queue1Handle,bx ; Handle der Queue sichern
pop cx
; ----------------------------
push cx
Write_String Open2Msg
; Öffnen der zweiten Queue (meldungsorientiert)
mov ax,01h
call OpenQueue
call CheckQueueError
if c jmp ErrorEnde1
mov Queue2Handle,bx ; Handle der Queue sichern
pop cx
; ----------------------------
Write_String Open3Msg
; Öffnen der dritten Queue (streamorientiert)
mov ax,0h
call OpenQueue
call CheckQueueError
if c jmp ErrorEnde1
mov Queue3Handle,bx ; Handle der Queue sichern
; ----------------------------
call ShowQueueData
if c jmp ErrorEnde1
; ----------------------------
Write_string ProceedMsg
mov B PunktZaehler,0
ReadLineLoop:
call LaufzeitAnzeige
call GetNextLine ; Zeile lesen
jc ReadLineLoopEnd ; EOF erreicht
mov cl,LineBuffer
xor ch,ch ; CX = Länge der Zeile
lea si,LineBuffer+1 ; DS:SI -> Zeile
jcxz WriteQueue3 ; leere Zeilen kommen in die Queue3
mov al,';'
cmp b[si],al
je WriteQueue1 ; Zeilen, die mit ';' beginnen kommen in
; die Queue1
mov es,cs
mov di,si
push cx
repne scasb
pop cx
je WriteQueue2 ; Zeilen, die nicht mit einem ';' beginnen,
; aber ein ';' enthalten kommen in
; die Queue2
; und alle anderen Zeilen kommen in Queue3
WriteQueue3:
mov bx,Queue3Handle
; CR und LF an die Zeile anhängen (falls möglich)
cmp cx,255 ; CX = Zeilenlänge
je >l1 ; nicht möglich
push bx
mov bx,cx
mov w[si+bx],LF by CR
pop bx
inc cx,2 ; und Zeilenlänge erhöhen
jmp >l1
WriteQueue2:
mov bx,Queue2Handle
jmp >l1
WriteQueue1:
mov bx,Queue1Handle
l1:
; DS:SI -> Meldung oder Byte für die Queue
; CX = Länge der Meldung oder Anzahl der Bytes
; BX = Handle der Queue
call WriteQueue ; WriteQueue entscheidet selbst, ob es sich
; um eine meldungs- oder streamorientierte
; Queue handelt.
call CheckQueueError
jnc ReadLineLoop
jmp ErrorEnde1
; ------------------
ReadLineLoopEnd:
mov B PunktZaehler,0
; Dateiende erreicht
call ShowCR_LF
call ShowQueueData
if c jmp ErrorEnde1
; ----------------------------
; 1. Queue ausgeben
Write_String Write1Msg
l00:
mov bx,Queue1Handle
mov cx,255
mov si,offset LineBuffer+1
call ReadQueue
call CheckQueueError
jnc >l1
call OutputMsg
call ShowCR_LF
jmp >l2 ; nächste Queue
l1:
; Zeile schreiben
mov bx,OutputFileHandle
mov dx,offset LineBuffer+1
mov ah,040h
int 021h
call CheckQueueError
if c jmp ErrorEnde1
mov dx,offset CR_LF ; CR_LF anhängen
mov cx,CR_LF_Length
mov ah,040h
int 021h
call CheckQueueError
jnc l00
jmp ErrorEnde1
; ----------------------------
l2:
Write_String Write2Msg
; 2. Queue ausgeben
l00:
mov bx,Queue2Handle
mov cx,255
mov si,offset LineBuffer+1
call ReadQueue
call CheckQueueError
jnc >l1
call OutputMsg
call ShowCR_LF
jmp >l2 ; nächste Queue
l1:
; Zeile schreiben
mov bx,OutputFileHandle
mov dx,offset LineBuffer+1
mov ah,040h
int 021h
call CheckQueueError
if c jmp ErrorEnde1
mov dx,offset CR_LF ; CR_LF anhängen
mov cx,CR_LF_Length
mov ah,040h
int 021h
call CheckQueueError
jnc l00
jmp ErrorEnde1
; ----------------------------
l2:
Write_String Write3Msg
; 3. Queue ausgeben
l00:
mov bx,Queue3Handle
mov cx,200
mov si,offset LineBuffer+1
call ReadQueue
call CheckQueueError
jnc >l1
call OutputMsg
call ShowCR_LF
jmp >l2 ; nächste Queue
l1:
; Bytes schreiben
mov bx,OutputFileHandle
mov dx,offset LineBuffer+1
mov ah,040h
int 021h
call CheckQueueError
jnc l00
jmp ErrorEnde1
; ----------------------------
l2:
call ShowQueueData
if c jmp ErrorEnde1
; Schliesse die Queuen
Write_String Close1Msg
mov bx,Queue1Handle
call CloseQueue
call CheckQueueError
jc ErrorEnde1
Write_String Close2Msg
mov bx,Queue2Handle
call CloseQueue
call CheckQueueError
jc ErrorEnde1
Write_String Close3Msg
mov bx,Queue3Handle
call CloseQueue
call CheckQueueError
jc ErrorEnde1
call GetMaxQueues
call CheckQueueError
jc ErrorEnde1
call ShowQueueStatistik
jmp SHORT Ende
; ------------------
ErrorEnde1:
push cx,dx
call ShowCR_LF
pop dx,cx
; Fehlerausgang
; DX = Offset der Meldung
; CX = Länge der Meldung
call OutputMsg
call ShowCR_LF
ErrorEnde:
mov al,0FFh
Ende:
; Ein- und Ausgabedateien schliessen
call CloseFiles
EndProcess
; ----------------------------
; ShowQueueData
;
; Funktion: Ausgabe der Daten aller Queuen und der globalen Daten
;
ShowQueueData:
mov bx,Queue1Handle
call GetQueueData ; Daten der Queue ausgeben
call CheckQueueError
jc ret
call ShowMHeader ; 1. Queue ist meldungsorientiert
mov bx,Queue2Handle
call GetQueueData ; Daten der Queue ausgeben
call CheckQueueError
jc ret
call ShowMHeader ; 2. Queue ist meldungsorientiert
mov bx,Queue3Handle
call GetQueueData ; Daten der Queue ausgeben
call CheckQueueError
jc ret
call ShowSHeader ; 1. Queue ist streamorientiert
call GetMaxQueues ; und die globalen Daten ausgeben
call CheckQueueError
jc ret
call ShowQueueStatistik
clc
ret
; ----------------------------
; ShowQueueStatistik
;
; Funktion: Ausgabe der globalen Werte
;
; Eingabe: Register wie von der Routine GetMaxQueues geliefert
;
QueuesStatMsg db CR,LF
db 'Daten der Queue-Verwaltung: '
db CR,LF
db 'Anzahl möglicher Queuen: '
m1 db '_____,'
db CR,LF
db 'Anzahl geöffneter Queuen: '
m2 db '_____'
db CR,LF
db 'davon streamorientiert: '
m3 db '___, '
db 'und meldungsorientiert: '
m4 db '___'
db CR,LF
GETLENGTH QueuesStatMsg
ShowQueueStatistik:
push es
mov es,cs
push ax
mov di,offset m4
call Konvert_AL_To_Dezstring
pop ax
mov al,ah
mov di,offset m3
call Konvert_AL_To_Dezstring
mov ax,cx
mov di,offset m2
call Konvert_AX_To_Dezstring
mov ax,dx
mov di,offset m1
call Konvert_AX_To_Dezstring
write_string QueuesStatMsg
pop es
ret
; ----------------------------
; ShowMHeader
;
; Funktion: Ausgabe der globalen Daten einer meldungsorientierten Queue
;
; Eingabe: AX, DX, CX und DI wie von der Routine GetQueueData geliefert
;
MHeaderMsg db CR,LF
db 'Daten der meldungs-orientierten Queue bei '
m3 db '____h: '
db CR,LF
db 'Gesamtspeicher: '
m4 db '_____, freier Speicher: '
m5 db '_____, '
m6 db '_____ Meldungen in der Queue'
db CR,LF
GETLENGTH MHeaderMsg
ShowMHeader:
push es
mov es,cs
push ax
mov ax,di
mov di,offset m3
call Konvert_AX_To_Hexstring
pop ax
mov di,offset m6
call Konvert_AX_To_Dezstring
mov di,offset m4
mov ax,dx
call Konvert_AX_To_Dezstring
mov di,offset m5
mov ax,cx
call Konvert_AX_To_Dezstring
Write_String MHeaderMsg
pop es
ret
; ----------------------------
; ShowSHeader
;
; Funktion: Ausgabe der globalen Daten einer streamorientierten Queue
;
; Eingabe: AX, DX, CX und DI wie von der Routine GetQueueData geliefert
;
SHeaderMsg db CR,LF
db 'Daten der stream-orientierten Queue bei '
m3 db '____h: '
db CR,LF
db 'Gesamtspeicher: '
m4 db '_____, freier Speicher: '
m5 db '_____, '
db 'belegter Speicher: '
m6 db '_____',CR,LF
GETLENGTH SHeaderMsg
ShowSHeader:
push es
mov es,cs
push ax
mov ax,di
mov di,offset m3
call Konvert_AX_To_Hexstring
pop ax
mov di,offset m6
call Konvert_AX_To_Dezstring
mov di,offset m4
mov ax,dx
call Konvert_AX_To_Dezstring
mov di,offset m5
mov ax,cx
call Konvert_AX_To_Dezstring
Write_String SHeaderMsg
pop es
ret
; ----------------------------
; CheckQueueError
;
; Funktion: Ermitteln der zu einer Fehlernummer der Routinen für die
; Verwaltung der Queuen gehörenden Fehlermeldung
;
; Eingabe: AX = Fehlercode der Routine
; CF = CF der Routine
;
; Ausgabe: CF = 0 ->> kein Fehler
; kein Register verändert
; CF = 1 ->> Fehler
; DX = Offset der Fehlermeldung
; CX = Länge der Fehlermeldung
; AX unverändert
;
; Fehlermeldungen der Routine aus
; MQUEUE.LIB
QueueErrorMsg1 db '*MQ* Keine weitere Meldung in der Queue!'
QueueErrorMsg2 db '*MQ* Nicht mehr genügend freier Speicher in der Queue!'
QueueErrorMsg3 db '*MQ* Falsche Größe für die Queue angegeben!'
QueueErrorMsg4 db '*MQ* Puffer ist für die nächste Meldung zu klein!'
QueueErrorMsg5 db '*MQ* Angegebene Meldung ist zu lang!'
QueueErrorMsg6 db '*MQ* Gleichzeitiger Zugriff von mehreren Routinen nicht erlaubt!'
; Fehlermeldungen der Routine aus
; SQUEUE.LIB
QueueErrorMsg7 db '*SQ* Kein weiteres Byte in der Queue!'
QueueErrorMsg8 db '*SQ* Nicht mehr genügend freier Speicher in der Queue!'
QueueErrorMsg9 db '*SQ* Falsche Größe für die Queue angegeben'
QueueErrorMsg10 db '*SQ* Gleichzeitiger Zugriff von mehreren Routinen nicht erlaubt!'
; Fehlermeldungen der Routine aus
; MEMORY.LIB
QueueErrorMsg11 db '*ME* Falsche Adresse angegeben!'
QueueErrorMsg12 db '*ME* Falsche Blockgröße angegeben!'
QueueErrorMsg13 db '*ME* Speicherblock ist frei!'
QueueErrorMsg14 db '*ME* Speicherblock gehört DOS!'
QueueErrorMsg15 db '*ME* Block ist kein Hauptblock!'
QueueErrorMsg16 db '*ME* Falscher Name für den Block angegeben!'
QueueErrorMsg17 db '*ME* Block nicht gefunden!'
; Fehlermeldungen der Routine aus
; QUEUES.LIB
QueueErrorMsg18 db '*QS* Funktion wird von der Queue nicht unterstützt!'
QueueErrorMsg19 db '*QS* Falsches Handle angegeben!'
QueueErrorMsg20 db '*QS* kein freies Handle mehr vorhanden!'
; DOS-Fehlermdeldungen
QueueErrorMsg21 db 'DOS: Fehlercode 07'
QueueErrorMsg22 db 'DOS: Fehlercode 08'
QueueErrorMsg23 db 'DOS: Fehlercode 09'
QueueErrorMsgU db '*** Unbekannter Fehlercode: '
UErrorCode db '____h!'
QueueErrorMsgL db 0 ; Dummy-Eintrag
; Tabelle der Fehlernummern und Fehlermeldungen
;
; Fehlernummer Offset der Fehlermeldung
; -----------------------------------------------
QueueErrorTable dw MQueueIsEmpty , Offset QueueErrorMsg1
dw MQueueIsFull , Offset QueueErrorMsg2
dw MQueueLengthError , Offset QueueErrorMsg3
dw MQueueBufferError , Offset QueueErrorMsg4
dw MQueueMessageError , Offset QueueErrorMsg5
dw MQueueAktivError , Offset QueueErrorMsg6
dw SQueueIsEmpty , Offset QueueErrorMsg7
dw SQueueIsFull , Offset QueueErrorMsg8
dw SQueueLengthError , Offset QueueErrorMsg9
dw SQueueAKtivError , Offset QueueErrorMsg10
dw MemoryBlockError , Offset QueueErrorMsg11
dw InvalidBlockLength , Offset QueueErrorMsg12
dw BlockIsFree , Offset QueueErrorMsg13
dw BlockBelongsToDOS , Offset QueueErrorMsg14
dw BlockIsNoMainBlock , Offset QueueErrorMsg15
dw InvalidBlockName , Offset QueueErrorMsg16
dw BlockNotFound , Offset QueueErrorMsg17
dw UnknownQSubFunction , Offset QueueErrorMsg18
dw InvalidQUeueHandle , Offset QueueErrorMsg19
dw NoMoreQueueHandles , Offset QueueErrorMsg20
dw 007 , Offset QueueErrorMsg21
dw 008 , Offset QueueErrorMsg22
dw 009 , Offset QueueErrorMsg23
; Eintrag für unbekannte Fehlercodes
QueueUnknownErr dw 0 , Offset QueueErrorMsgU
; Eintrag für die Ermittlung der Länge
; der letzten Fehlermeldung
dw 0 , Offset QueueErrorMsgL
CheckQueueError:
jnc ret ; CF = 0 ->> kein Fehler aufgetreten
push si,ds,ax ; CF = 1 ->> Fehler aufgetreten,
; Offset der Fehlermeldung ermitteln
mov ds,cs ; DS = CS
mov si,offset QueueErrorTable
; DS:SI -> Fehlertabelle
; Eintrag für unbekannte Fehlercodes korrigieren
mov QueueUnknownErr,ax
push es,di,ax
mov es,cs
mov di,offset UErrorCode
call Konvert_AX_To_HexString
pop ax,di,es
mov dx,ax ; Fehlernummer nach DX
l0:
lodsw
cmp ax,dx
lodsw
jne l0
mov dx,ax ; DX = Offset der Fehlermeldung
mov cx,[si+2] ; CX = Offset der nächsten Fehlermeldung
sub cx,dx ; CX = Länge der Fehlermeldung
stc
pop ax,ds,si
ret
; ----------------------------
; OpenInAndOutputFiles
;
; Funktion: Öffnet die Ein- und Ausgabe-Dateien und liest die Eingabe-Datei
;
; Ausgabe: CF = 0 ->> okay
; CF = 1 ->> Fehler
; DX = Offset der Fehlermeldung
; CX = Länge der Fehlermeldung
;
OpenInAndOutputFiles:
mov bx,1000h ; Speicher zum Lesen der Eingabe-Datei anfordern
mov ah,048h ; 1 Segment
int 021h
jnc >l1
; Fehler, nicht genügend Speicher vorhanden
mov dx,offset MemoryError
mov cx,MemoryError_LENGTH
stc
ret
; ------------------
l1:
mov InputFileSeg,ax ; Segment sichern
mov si,080h ; Parameter bearbeiten
lodsb
or al,al
jnz >l1
; Fehler: Keine Parameter angegeben
ParameterError:
mov dx,offset ParamError
mov cx,ParamError_LENGTH
stc
ret
; ------------------
l1:
call GetFileName ; Anfang des ersten Dateinamens suchen
jc ParameterError
; DS:DX -> erster Dateiname als ASCIIZ-String
; ------------------
mov ax,03D02h ; Eingabe-Datei öffnen
int 021h
jnc >l1
; ------------------
InputFileError:
mov dx,offset IFileError
mov cx,IFileError_LENGTH
stc
ret
; ------------------
l1:
mov InputFileHandle,ax ; Handle der Eingabe-Datei sichern
; ------------------
call GetFileName ; Name der Ausgabe-Datei ermitteln
jc ParameterError
; ------------------
; Ausgabe-Datei anlegen
mov cx,0 ; CX = Standard-Attribte
mov ah,03Ch ; Datei erstellen
int 021h
jnc >l1
; ------------------
OutputFileError:
mov dx,offset OFileError
mov cx,OFileError_LENGTH
stc
ret
; ------------------
l1:
mov OutputFileHandle,ax ; Handle der Ausgabe-Datei sichern
; ------------------
mov ah,03Fh ; und Eingabe-Datei lesen
mov cx,0FFF5h
mov bx,InputFileHandle
lds dx,InputFileOff ; DS <> CS
int 021h
mov ds,cs ; DS = CS
jc InputFileError
cmp ax,cx
jb >l1
; ------------------
InputFileError1:
mov dx,offset IFileError1
mov cx,IFileError1_LENGTH
stc
ret
; ------------------
l1:
mov InputFileLength,ax ; Länge der Datei sichern
clc
ret
; ----------------------------
; GetFileName
;
; Funktion: Ermittelt den nächsten Parameter und konvertiert ihn in
; einen ASCIIZ-String
;
; Eingabe: SI -> Ende des letzte Parameters
;
; Ausgabe: CF = 0 ->> okay, DX -> Anfang des Parameters
; CF = 1 ->> Fehler
;
GetFileName:
l0: ; Anfang des Parameters suchen
lodsb
cmp al,BLANK
je l0
cmp al,TAB
je l0
cmp al,CR
je >l8
; ------------------
lea dx,[si-1] ; Anfang des Parameters gefunden
l1: ; Ende des Parameters suchen
lodsb
cmp al,BLANK
je >l2
cmp al,TAB
je >l2
cmp al,CR
je >l2
jmp l1
l2:
mov b[si-1],0 ; Nullbyte eintragen
clc
ret
; ------------------
l8:
stc
ret
; ----------------------------
; GetNextLine
;
; Funktion: Ermittelt die nächste Zeile der Eingabe-Datei aus dem Puffer
;
; Eingabe: DS = CS
;
; Ausgabe: CF = 0 ->> LineBuffer ist gefüllt
; CF = 1 ->> EOF erreicht
;
GetNextLine:
mov ax,InputFileOff
cmp ax,InputFileLength
jb >l1
stc ; EOF erreicht
ret
l1:
push ds,es,si,di,cx
mov es,cs ; ES = CS
mov di,offset LineBuffer
; ES:DI -> Längenzähler des Zeilenpuffers
xor cx,cx ; CX = Längenzähler
lds si,cs:InputFileOff ; DS:SI -> akt. Position im Puffer
push di
inc di ; ES:DI -> Zeilenpuffer
l0:
cmp cl,255xD ; max. Zeilenlänge erreicht?
je >l1 ; ja
lodsb
cmp al,CR
je >l1 ; Zeilenende erreicht
stosb ; Zeichen übernehmen
inc cx ; Zähler korrigieren
jmp l0
l1:
cmp b[si],LF
if e inc si ; LF am Zeilenende überlesen
pop di
mov es:[di],cl ; Länge der Zeile eintragen
mov cs:InputFileOff,si ; und Pufferzeiger sichern
l9:
clc
pop cx,di,si,es,ds
ret